package org.tloss.proxyserver.filter;

import java.io.IOException;
import java.util.UUID;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.tloss.proxyserver.Constants;
import org.tloss.proxyserver.ProxyContextEntry;
import org.tloss.proxyserver.ProxyEntry;
import org.tloss.proxyserver.ProxyMangager;
import org.tloss.proxyserver.UserInfo;
import org.tloss.proxyserver.datasource.DataSource;

public class AdminFilterHandler implements FilterHandler {
	DataSource dataSource = DataSource.getInstanse();

	protected boolean requireLogin(HttpServletRequest request,
			HttpServletResponse response) throws IOException, ServletException {
		HttpSession session = request.getSession(true);
		if (session == null || session.getAttribute("userInfo") == null) {
			response.sendRedirect(response.encodeURL(request.getContextPath()
					+ Constants.INDEX_PATH));
			return true;
		}
		return false;
	}

	public void doFilter(String URI, HttpServletRequest request,
			HttpServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		if (URI.startsWith(Constants.LOGIN_POST_PATH)) {
			if ("POST".equalsIgnoreCase(request.getMethod())) {
				String userName = request.getParameter("email");
				String password = request.getParameter("password");
				if (!(userName == null || "".equals(userName)
						|| password == null || "".equals(password))) {
					UserInfo info = dataSource.getUserInfo(userName, password);
					if (info != null) {
						HttpSession session = request.getSession(true);
						session.setAttribute("userInfo", info);
						response.sendRedirect(response.encodeURL(request
								.getContextPath() + Constants.INDEX_PATH));
						return;
					} else {
						request.setAttribute("error",
								"Wrong username or password!");
						// wrong password
					}
				} else {
					request.setAttribute("error",
							"username or password is empty!");
					// error
				}
				handlerDefaultPage(request, response);
			} else {
				response.sendRedirect(request.getContextPath()
						+ Constants.LOGIN_PATH);
			}
		} else if (URI.startsWith(Constants.LOGIN_LOGOUT_PATH)) {
			HttpSession session = request.getSession(true);
			if (session != null) {
				session.invalidate();
			}
			response.sendRedirect(response.encodeURL(request.getContextPath()
					+ Constants.LOGIN_PATH));
		} else if (URI.startsWith(Constants.ADD_CONTEXT_PATH)) {
			if(requireLogin(request,response))
				return;
			if ("POST".equalsIgnoreCase(request.getMethod())) {
				String context = request.getParameter("context");
				String status = request.getParameter("status");
				if (!(context == null || "".endsWith(context) || status == null || ""
						.equals(status))) {
					if (context.startsWith("/")) {
						int s = -1;
						try {
							s = Integer.parseInt(status);
						} catch (Exception e) {
						}
						if (s == ProxyContextEntry.ENABLE
								|| s == ProxyContextEntry.DISABLE) {
							if (!(Constants.PROXY_ADMIN_PATH.equals(context) || Constants.PROXY_RESOURCES_PATH
									.equals(context))) {
								ProxyMangager mangager = ProxyMangager
										.getInstanse();
								if (mangager.addNewContextEntry(context,
										s == ProxyContextEntry.ENABLE)) {
									request.setAttribute("success", "Context :"
											+ context + " have been added.");
								} else {
									request.setAttribute("error",
											"Fail to add context :" + context
													+ ".");
								}
							} else {
								request.setAttribute("error", "context "
										+ Constants.PROXY_ADMIN_PATH + " or "
										+ Constants.PROXY_RESOURCES_PATH
										+ " is not allow");
							}
						} else {
							request.setAttribute("error", "invalid status");
						}

					} else {
						request.setAttribute("error",
								"context must be start with /!");
					}
				} else {
					request.setAttribute("error", "context and status is empty");
					// invalid input
				}
			}
			request.getRequestDispatcher("/proxyadmin/jsp/add-context.jsp")
					.include(request, response);
		} else if (URI.startsWith(Constants.LIST_PROXY_ENTRY_PATH)) {
			if(requireLogin(request,response))
				return;
			String context = request.getParameter("context");
			ProxyMangager mangager = ProxyMangager.getInstanse();
			request.setAttribute("proxyEntries",
					mangager.getProxyEntries(context));
			request.setAttribute("context", context);
			request.getRequestDispatcher("/proxyadmin/jsp/list-proxy-entry.jsp")
					.include(request, response);
		} else if (URI.startsWith(Constants.ADD_PROXY_ENTRY_PATH)) {
			if(requireLogin(request,response))
				return;
			String proxyContext = request.getParameter("proxyContext");
			request.setAttribute("proxyContext", proxyContext);
			if ("POST".equalsIgnoreCase(request.getMethod())) {
				String status = request.getParameter("status");
				String context = request.getParameter("context");
				String port = request.getParameter("port");
				String host = request.getParameter("host");
				String protocol = request.getParameter("protocol");
				String hash = UUID.randomUUID().toString();
				ProxyEntry entry = new ProxyEntry();
				entry.setContext(context);
				entry.setHash(hash);
				entry.setHost(host);
				entry.setPort(Integer.parseInt(port));
				entry.setProtocol(protocol);
				entry.setProxyContext(proxyContext);
				entry.setStatus(Integer.parseInt(status));
				ProxyMangager mangager = ProxyMangager.getInstanse();
				if (mangager.addNewProxyEntry(entry)) {
					request.setAttribute("success", "hash :" + hash
							+ " have been added.");
				} else {
					request.setAttribute("error", "Fail to add hash:" + hash
							+ ".");
				}
			}
			request.getRequestDispatcher("/proxyadmin/jsp/add-proxy-entry.jsp")
					.include(request, response);
		} else if (URI.startsWith(Constants.LOGIN_PATH)
				|| URI.startsWith(Constants.INDEX_PATH)) {
			handlerDefaultPage(request, response);
		} else {
			chain.doFilter(request, response);
		}
	}

	protected void handlerDefaultPage(HttpServletRequest request,
			HttpServletResponse response) throws IOException, ServletException {
		HttpSession session = request.getSession(true);
		if (session != null && session.getAttribute("userInfo") != null) {
			request.getRequestDispatcher("/proxyadmin/jsp/admin.jsp").include(
					request, response);
		} else {
			request.getRequestDispatcher("/proxyadmin/jsp/login.jsp").include(
					request, response);
		}
	}

	
	public void init() {
		
	}

	
	public void destroy() {
		
		
	}
}
